
import { init, parse } from "es-module-lexer";
import {
  BARE_IMPORT_RE,
  DEFAULT_EXTERSIONS,
  PRE_BUNDLE_DIR,
  CLIENT_PUBLIC_PATH
} from "../constants";
import type {
  LoadResult,
  PartialResolvedId,
  SourceDescription,
  PluginContext as RollupPluginContext,
  ResolvedId,

} from "rollup";
import {
  cleanUrl,
  isJSRequest,
  normalizePath,
  relativeUrl,
  getShortName,
  isInternalRequest
} from "../utils";
// magic-string 用来作字符串编辑
import MagicString from "magic-string";
import path from "path";
import { Plugin } from "../plugin";
import { ServerContext } from "../server/index";
import { pathExists } from "fs-extra";

export function importAnalysis(): Plugin {
  let serverContext: ServerContext;
  return {
    name: "m-vite:import-analysis",
    configureServer(s) {
      // 保存服务端上下文
      serverContext = s;
    },
    async transform(code: string, id: string) {

      if (!isJSRequest(id) || isInternalRequest(id)) {
        return null
      }

      await init;
      const [imports] = parse(code);
      const ms = new MagicString(code);

      const resolve = async (id: string, importer?: string) => {
        const resolved = await serverContext.pluginContainer.resolveId(
          id,
          normalizePath(importer as string)
        );
        if (!resolved) {
          return;
        }
        const cleanedId = cleanUrl(resolved.id);
        const mod = moduleGraph.getModuleById(cleanedId);



        let resolvedId = `/${getShortName(resolved.id, serverContext.root)}`;
        if (mod && mod.lastHMRTimestamp > 0) {
          resolvedId += "?t=" + mod.lastHMRTimestamp;
        }
        return resolvedId;
      };
      const { moduleGraph } = serverContext;
      const curMod = moduleGraph.getModuleById(id)!;
      const importedModules = new Set<string>();

      for (const importInfo of imports) {
        const { s: modStart, e: modEnd, n: modSource } = importInfo;

        // console.log(modStart, modEnd, modSource)
        if (!modSource) continue;

        if (modSource.endsWith(".svg")) {

          const resolvedUrl = relativeUrl(path.join(path.dirname(id), modSource))

          ms.overwrite(modStart, modEnd, `${resolvedUrl}?import`);
          continue;
        }
        if (BARE_IMPORT_RE.test(modSource)) {
          //服务开始阶段，已经使用esbuild将main.tsx打包了，这个是讲路径导过去
          const bundlePath = normalizePath(
            path.join('/', PRE_BUNDLE_DIR, `${modSource}.js`)
          );

          ms.overwrite(modStart, modEnd, bundlePath);
          importedModules.add(bundlePath);
          // console.log(bundlePath)
        }
        else if (modSource.startsWith(".") || modSource.startsWith("/")) {
          //   // 直接调用插件上下文的 resolve 方法，会自动经过路径解析插件的处理


          const resolved = await resolve(modSource, id);

          if (resolved) {
            ms.overwrite(modStart, modEnd, resolved);
            importedModules.add(resolved);
          }

        }
      }
      if (!id.includes("node_modules")) {
        ms.prepend(
          `import { createHotContext as __vite__createHotContext } from "${CLIENT_PUBLIC_PATH}";` +
          `import.meta.hot = __vite__createHotContext(${JSON.stringify(
            cleanUrl(curMod.url)
          )});`
        );
      }
      moduleGraph.updateModuleInfo(curMod, importedModules);
      return {
        code: ms.toString(),
        // 生成 SourceMap
        map: ms.generateMap(),
      };

    }
  }
}